package com.jmebananas.bounding;

import java.nio.FloatBuffer;
import java.util.ArrayList;

import com.jme.bounding.BoundingBox;
import com.jme.bounding.BoundingVolume;
import com.jme.math.Quaternion;
import com.jme.math.Triangle;
import com.jme.math.Vector3f;
import com.jme.scene.batch.TriangleBatch;

/**
 * InfiniteBound
 * 
 * @author Glenn Powell
 * 
 */
public class MinimumBoundingBox extends BoundingBox {

	private static final long serialVersionUID = 1L;
	
	
	private Vector3f minimum = new Vector3f();


	public BoundingVolume clone(BoundingVolume store) {
		if (store == null) {
			MinimumBoundingBox box = new MinimumBoundingBox();
			box.setMinimum(minimum.clone());
			store = box;
		}
		BoundingVolume volume = super.clone(store);
		if (volume.getType() == BoundingVolume.BOUNDING_BOX) {
			applyMinimum((BoundingBox) volume);
		}
		return volume;
	}
	
	public Vector3f getMinimum() {
		return minimum;
	}
	
	public void setMinimum(Vector3f minimum) {
		this.minimum = minimum;
	}
	
	private void applyMinimum(BoundingBox box) {
		if (box.xExtent < minimum.x)
			box.xExtent = minimum.x;
		if (box.yExtent < minimum.y)
			box.yExtent = minimum.y;
		if (box.zExtent < minimum.z)
			box.zExtent = minimum.z;
	}

	@SuppressWarnings("unchecked")
	public void computeFromBatches(ArrayList batches) {
		super.computeFromBatches(batches);
		applyMinimum(this);
	}

	public void computeFromPoints(FloatBuffer points) {
		super.computeFromPoints(points);
		applyMinimum(this);
	}

	public void computeFromTris(int[] triIndex, TriangleBatch batch, int start, int end) {
		super.computeFromTris(triIndex, batch, start, end);
		applyMinimum(this);
	}

	public void computeFromTris(Triangle[] tris, int start, int end) {
		super.computeFromTris(tris, start, end);
		applyMinimum(this);
	}

	public BoundingVolume merge(BoundingVolume volume) {
		volume = super.merge(volume);
		if (volume.getType() == BoundingVolume.BOUNDING_BOX) {
			applyMinimum((BoundingBox) volume);
		}
		return volume;
	}

	public BoundingVolume mergeLocal(BoundingVolume volume) {
		volume = super.mergeLocal(volume);
		if (volume.getType() == BoundingVolume.BOUNDING_BOX) {
			applyMinimum((BoundingBox) volume);
		}
		return volume;
	}

	public BoundingVolume transform(Quaternion rotate, Vector3f translate, Vector3f scale, BoundingVolume store) {
		if (store == null) {
			MinimumBoundingBox box = new MinimumBoundingBox();
			box.setMinimum(minimum.clone());
			store = box;
		}
		BoundingVolume volume = super.transform(rotate, translate, scale, store);
		if (volume.getType() == BoundingVolume.BOUNDING_BOX) {
			applyMinimum((BoundingBox) volume);
		}
		return volume;
	}

}
